#include <pthread.h>
#include <string>
#include <semaphore.h>
#include <unistd.h>

int tickets = 1500; 
#define Thread_num 4

class ThreadData
{
public:
    ThreadData(const std::string& name,sem_t* sem_tickets) : _name(name),_sem_tickets(sem_tickets){}
    std::string _name; 
    sem_t *_sem_tickets;
};

//抢票线程执行逻辑
void* BuyTicket(void* args)
{
     ThreadData* td = (ThreadData*)args;
     while(true)
     {
        usleep(1000);
        sem_wait(td->_sem_tickets); // P 操作 
        int x;
        sem_getvalue(td->_sem_tickets,&x);
        printf("%s 抢了一张票，还剩下 : %d\n",td->_name.c_str(),x);
     }
}


//放票线程执行逻辑
void* PutTicket(void* args)
{
     ThreadData* td = (ThreadData*)args;
     while(true)
     {
        sleep(1);
        sem_post(td->_sem_tickets); // V 操作 
        int x;
        sem_getvalue(td->_sem_tickets,&x);
         printf("%s 放了一张票，票数 : %d\n",td->_name.c_str(),x);
     }
}

int main()
{
    pthread_t tids[Thread_num]; //开四个线程，三个线程抢票，一个线程放票
    sem_t sem_tickets; 
    sem_init(&sem_tickets,0,tickets); //创建信号量
    for(int i = 0 ; i < Thread_num ; i ++)
    { 
        if(i == 0)
        {
            //创建放票线程
            std::string name = "放票 thread " + std::to_string(i + 1);
            ThreadData* td = new ThreadData(name,&sem_tickets);
            pthread_create(tids+i, nullptr,PutTicket,(void*)td);
        }
        else{
            //创建抢票线程
            std::string name = "抢票 thread " + std::to_string(i + 1);
            ThreadData* td = new ThreadData(name,&sem_tickets);
            pthread_create(tids+i, nullptr,BuyTicket,(void*)td);
        }
    }

    for(int i = 0 ; i < Thread_num; i ++)
    {
        pthread_join(tids[i],nullptr);
    }
    sem_destroy(&sem_tickets);
    return 0 ;
}